package com.ydlclass.ChannelHandler.handler.OutboundHandler;

import com.ydlclass.Transport.message.MessageFormatConstant;
import com.ydlclass.Transport.message.Request.RequestPayload;
import com.ydlclass.Transport.message.Response.YrpcResponse;
import com.ydlclass.compress.Compress;
import com.ydlclass.compress.CompressFactory;
import com.ydlclass.serialize.Serialize;
import com.ydlclass.serialize.SerializerFactory;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.List;

/**
 * YrpcResponse响应编码器
 *
 * 4B  magic(魔术)
 * 1B  version(版本)
 * 2B  header length (头部长度)
 * 4B  full  length (总长度)
 * 1B  Response type (响应类型)
 * 1B  serialize (序列化类型)
 * 1B  compress (压缩类型)
 * 8B  requestId (请求ID)
 * object对象
 * @Author duWenJian
 * @Date 2024/2/21 20:43
 * @Version 1.0
 */
@Slf4j
public class YrpcMessageResponseEncoderHandler extends MessageToMessageEncoder<YrpcResponse> {
    @Override
    protected void encode(ChannelHandlerContext ctx, YrpcResponse yrpcResponse, List<Object> out) throws Exception {
        ByteBuf buf = ctx.alloc().buffer();
        // 魔术值 占4个字节
        buf.writeBytes(MessageFormatConstant.MAGIC);
        // 版本号 占1个字节
        buf.writeByte(MessageFormatConstant.VERSION);
        // 头部长度 占2个字节
        buf.writeShort(MessageFormatConstant.HEAD_LENGTH);
        // todo 总长度 占4个字节,不知道body的长度,
        //  保存当前写指针的位置 writeIndex(写指针) 往后移动4个位置，等Object长度计算出来之后，再计算FULL_LENGTH
        buf.markWriterIndex();
        buf.writerIndex(buf.writerIndex() + MessageFormatConstant.FULL_FIELD_LENGTH);
        // 响应状态码 占1个字节 序列化类型 占1个字节 压缩类型 占1个字节
        buf.writeByte(yrpcResponse.getResponseCode());
        buf.writeByte(yrpcResponse.getSerializeType());
        buf.writeByte(yrpcResponse.getCompressType());
        // 请求Id 占8个字节
        buf.writeLong(yrpcResponse.getRequestId());
        // 请求时间戳 占8个字节
        buf.writeLong(yrpcResponse.getTimeStamp());

        // 响应体body 经过计算算出

        byte[] compressBytes = null;

        if (yrpcResponse.getResponseBody() != null ){
        Serialize serialize = SerializerFactory.getSerializer(yrpcResponse.getSerializeType()).getImpl();
        byte[] body = serialize.serialize(yrpcResponse.getResponseBody());
        // 压缩
        Compress compress = CompressFactory.getCompress(yrpcResponse.getCompressType()).getImpl();
         compressBytes = compress.compress(body);
        }

        if (compressBytes != null){
            buf.writeBytes(compressBytes);
        }

        int bodyLength = compressBytes == null ? 0 : compressBytes.length;
        // 保存当前写指针的位置
        int index = buf.writerIndex();
        buf.resetWriterIndex();
        buf.writeInt(MessageFormatConstant.HEAD_LENGTH + bodyLength);
        // 写指针回来
        buf.writerIndex(index);
        out.add(buf);
    }
}
